
<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />

    <title>Developing LAVA on Debian &#8212; LAVA 2024.05 documentation</title>
    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css" />
    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
    <script src="_static/jquery.js"></script>
    <script src="_static/underscore.js"></script>
    <script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
    <script src="_static/doctools.js"></script>
    <script src="_static/sphinx_highlight.js"></script>
    <link rel="shortcut icon" href="_static/favicon.ico"/>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Packaging lava-server for distributions" href="packaging.html" />
    <link rel="prev" title="Testing the design" href="dispatcher-testing.html" />
    <link rel="canonical" href="https://docs.lavasoftware.org/lava/debian.html" />
  
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
<script type="text/javascript" src="_static/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="_static/js/jquery-fix.js"></script>
<script type="text/javascript" src="_static/bootstrap-3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="_static/bootstrap-sphinx.js"></script>


  </head><body>

  <div id="navbar" class="navbar navbar-default navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="index.html"><span><img src="_static/lava.png"></span>
          LAVA</a>
        <span class="navbar-text navbar-version pull-left"><b>2024.05</b></span>
      </div>

        <div class="collapse navbar-collapse nav-collapse">
          <ul class="nav navbar-nav">
            
                <li><a href="genindex.html">Index</a></li>
                <li><a href="contents.html">Contents</a></li>
            
            
              <li class="dropdown globaltoc-container">
  <a role="button"
     id="dLabelGlobalToc"
     data-toggle="dropdown"
     data-target="#"
     href="index.html">Site <b class="caret"></b></a>
  <ul class="dropdown-menu globaltoc"
      role="menu"
      aria-labelledby="dLabelGlobalToc"><ul class="current">
<li class="toctree-l1"><a class="reference internal" href="index.html">Introduction to LAVA</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="contents.html">Contents</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="glossary.html">Glossary of terms</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="support.html">Getting support</a></li>
</ul>
</ul>
</li>
              
                <li class="dropdown">
  <a role="button"
     id="dLabelLocalToc"
     data-toggle="dropdown"
     data-target="#"
     href="#">Page <b class="caret"></b></a>
  <ul class="dropdown-menu localtoc"
      role="menu"
      aria-labelledby="dLabelLocalToc"><ul>
<li><a class="reference internal" href="#">Developing LAVA on Debian</a><ul>
<li><a class="reference internal" href="#why-debian">Why Debian?</a></li>
<li><a class="reference internal" href="#options-for-other-distributions">Options for other distributions</a></li>
<li><a class="reference internal" href="#preparing-for-lava-development">Preparing for LAVA development</a></li>
<li><a class="reference internal" href="#developer-package-build">Developer package build</a><ul>
<li><a class="reference internal" href="#changes-from-2018-10-onwards">Changes from 2018.10 onwards</a></li>
<li><a class="reference internal" href="#which-branch-to-use-for-changes">Which branch to use for changes</a></li>
<li><a class="reference internal" href="#local-version-strings">Local version strings</a></li>
<li><a class="reference internal" href="#distribution-differences">Distribution differences</a></li>
<li><a class="reference internal" href="#example">Example</a></li>
<li><a class="reference internal" href="#developer-build-versions">Developer build versions</a></li>
</ul>
</li>
<li><a class="reference internal" href="#development-using-python3">Development using Python3</a></li>
<li><a class="reference internal" href="#quick-fixes-and-testing">Quick fixes and testing</a></li>
<li><a class="reference internal" href="#viewing-changes">Viewing changes</a></li>
<li><a class="reference internal" href="#migrating-postgresql-versions">Migrating postgresql versions</a><ul>
<li><a class="reference internal" href="#determining-the-active-cluster">Determining the active cluster</a></li>
<li><a class="reference internal" href="#performing-the-migration">Performing the migration</a></li>
</ul>
</li>
<li><a class="reference internal" href="#dependency-requirements">Dependency Requirements</a><ul>
<li><a class="reference internal" href="#outputting-the-requirements-txt-format">Outputting the requirements.txt format</a></li>
<li><a class="reference internal" href="#outputting-a-list-of-binary-package-names">Outputting a list of binary package names</a></li>
<li><a class="reference internal" href="#adding-packages-needed-for-the-unittests">Adding packages needed for the unittests</a></li>
</ul>
</li>
<li><a class="reference internal" href="#javascript-handling">Javascript handling</a><ul>
<li><a class="reference internal" href="#javascript-and-security">Javascript and security</a></li>
<li><a class="reference internal" href="#javascript-maintenance">Javascript maintenance</a></li>
<li><a class="reference internal" href="#packaging-changes">Packaging changes</a></li>
<li><a class="reference internal" href="#building-for-other-architectures">Building for other architectures</a></li>
</ul>
</li>
<li><a class="reference internal" href="#debugging-django-issues">Debugging Django issues</a><ul>
<li><a class="reference internal" href="#installing">Installing</a></li>
<li><a class="reference internal" href="#configuration">Configuration</a></li>
<li><a class="reference internal" href="#performance-overhead">Performance overhead</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
</li>
              
            
            
              
                
  <li>
    <a href="dispatcher-testing.html" title="Previous Chapter: Testing the design"><span class="glyphicon glyphicon-chevron-left visible-sm"></span><span class="hidden-sm hidden-tablet">&laquo; Testing the design</span>
    </a>
  </li>
  <li>
    <a href="packaging.html" title="Next Chapter: Packaging lava-server for distributions"><span class="glyphicon glyphicon-chevron-right visible-sm"></span><span class="hidden-sm hidden-tablet">Packaging lav... &raquo;</span>
    </a>
  </li>
              
            
            
            
            
              <li class="hidden-sm"></li>
            
          </ul>

          
            
<form class="navbar-form navbar-right" action="search.html" method="get">
 <div class="form-group">
  <input type="text" name="q" class="form-control" placeholder="Search" />
 </div>
  <input type="hidden" name="check_keywords" value="yes" />
  <input type="hidden" name="area" value="default" />
</form>
          
        </div>
    </div>
  </div>

<div class="container">
  <div class="row">
    <div class="body col-md-12 content" role="main">
      
  <section id="developing-lava-on-debian">
<span id="lava-on-debian"></span><span id="index-0"></span><h1>Developing LAVA on Debian<a class="headerlink" href="#developing-lava-on-debian" title="Permalink to this heading">¶</a></h1>
<p>LAVA no longer supports development on Ubuntu.</p>
<p>Packages for LAVA are available for:</p>
<ul class="simple">
<li><p>Debian Buster (testing)</p></li>
<li><p>Debian Sid (unstable)</p></li>
</ul>
<p>When using the packages to develop LAVA, there is a change to the workflow
compared to the old lava-deployment-tool buildouts.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Changes to build dependencies between Debian versions can
cause changes to the builds for each suite. Always ensure that you
build packages for unstable using unstable and build packages for
stable using a chroot or VM or other stable environment. If a
package built on unstable does not install on stable, rebuild the
same changes in a stable environment and re-install. Backports to
stable in Debian are always built in a stable chroot or VM for this
reason.</p>
</div>
<section id="why-debian">
<h2>Why Debian?<a class="headerlink" href="#why-debian" title="Permalink to this heading">¶</a></h2>
<p>In the very early stages, LAVA was deployed using a custom script based
on PyPi and a lot of manual effort. This deployment tool frequently
failed in complex and unexpected ways. It become clear that this would
block successful and reliable deployment and upgrades of LAVA,
particularly in larger scale environments.</p>
<p>The main LAVA developer at the time was also a Debian developer with
the rights and familiarity with Debian to convert the deployment tool
into a packaged format which solved these issues.</p>
<p>LAVA is not inherently tied to Debian but following the route of
packaging LAVA in Debian solved many issues very easily. By using a
well supported and readily understood distribution as our base, many
users have been able to install and operate LAVA without needing direct
help from the developers. We have also gained a stable and reliable
platform for our internal CI which was an enormous aid during the V2
development cycle.</p>
<p>Whilst it might seem that lots of developer time is spent doing Debian
specific development, equivalent (and possibly more) work would be
needed to develop and support LAVA on any platform. Debian provides a
very large collection of packaged software, removing the need for us to
package and maintain the full stack which LAVA needs.</p>
</section>
<section id="options-for-other-distributions">
<span id="lava-on-other-distros"></span><span id="index-1"></span><h2>Options for other distributions<a class="headerlink" href="#options-for-other-distributions" title="Permalink to this heading">¶</a></h2>
<p>Although LAVA is not inherently tied to the Debian distribution, there
would be some work involved to ensure that another method of
deploying LAVA would work well enough for the upstream LAVA team to
officially support that method.</p>
<p>On top of developing LAVA itself, full support of LAVA in Debian
includes:</p>
<ol class="arabic">
<li><p>Maintenance of packaging code, either upstream or in a public git
repository.</p></li>
<li><p>Preparation of LAVA releases for inclusion into the distribution.</p></li>
<li><p>Rights to upload LAVA releases to the distribution and access
within the distribution to apply local patches, upload security
fixes and provide for backporting newer dependencies to maintain
support for existing releases.</p></li>
<li><p>Maintenance of a LAVA lab using this distribution and running CI
on LAVA devices. (This is to ensure that the functionality of LAVA
is being tested on this distribution. It would be very useful, for
example. for such a lab to participate in functional testing of LAVA
upstream.)</p></li>
<li><p>Sufficient involvement in the distribution and familiarity with
the distribution release process to provide full support for both
installing new instances and smoothly upgrading established
instances to each new release of the distribution.</p>
<p>This includes planning ahead to ensure that new dependencies are
packaged for the distribution in time for the next distribution
release.</p>
</li>
<li><p>Maintenance of LAVA releases within the distribution across more
than one distribution release cycle, at the same time.</p>
<p>This is to ensure that users have continuity of support and can
choose when to migrate the base operating system of their labs.</p>
</li>
<li><p>Involvement on IRC and mailing lists to promptly support users
experiencing problems with using LAVA on the distribution.</p></li>
<li><p>Maintenance of the LAVA documentation covering how to use LAVA on
the distribution.</p></li>
<li><p>Triage and fixing of issues in LAVA which are specific to the
distribution.</p></li>
<li><p>Discussion with the rest of LAVA Software Community Project
development team around issues related to this distribution.</p></li>
<li><p>Use of all available tools within the distribution to anticipate
problems. Where possible, implementation of fixes before users are
affected.</p></li>
<li><p>Maintenance of dependencies using <code class="docutils literal notranslate"><span class="pre">./share/requires.py</span></code> to enable
automated testing. This includes testing the versions of specific
dependencies and ensuring that the minimum version is available in
all supported releases of the distribution.</p></li>
<li><p>Maintenance of scripts which build Docker images for and using that
distribution, including publishing such images. These images will be
required to support the internal CI.</p></li>
<li><p>Maintenance of upstream LAVA CI using that distribution in Docker to
run the unit tests as well as build and test the packaging of LAVA
for that distribution. This CI will involve, at a minimum, running
such tests on the currently supported distribution release <strong>and</strong>
the candidate for the next distribution release.</p></li>
<li><p>Maintenance of upstream CI using <code class="docutils literal notranslate"><span class="pre">gitlab-runner</span></code> on a machine
running the relevant distribution so that CI jobs on the new
distribution run in parallel to the CI jobs running on Debian.</p></li>
<li><p>Maintenance of LAVA tools and support scripts for running a LAVA lab
using the distribution.</p></li>
<li><p>Consideration that support for the distribution may involve
supporting more than one system architecture.</p></li>
</ol>
<p>As an example from LAVA’s history, support for migrations between
releases was the main problem for LAVA support of Ubuntu. It became
impossible to provide a smooth upgrade path from one Ubuntu LTS release
(14.04 Trusty) to the next LTS release (16.04 Xenial). LAVA needs to
provide long term stability to provide reliable CI whilst keeping up
with changes across supported distributions and tools. For the sake of
lab admin workload, support needs to concentrate on LTS or server level
releases rather than developer releases or interim updates. Even though
Ubuntu is closely related to Debian, the timing of Ubuntu releases made
it very difficult to manage complex transitions like the change from
Django 1.4 to 1.8 and this was also a concern for the transition to
Python3.</p>
<p>You may find that more than one person will be required to meet all
these criteria and to maintain that support across several releases of
the distribution. The current LAVA Software Community Project team does
not have enough resources to do this work for any distribution other
than Debian.</p>
<p><a class="reference internal" href="support.html#mailing-lists"><span class="std std-ref">Talk to us</span></a> before spending time on such work.</p>
</section>
<section id="preparing-for-lava-development">
<span id="developer-preparations"></span><span id="index-2"></span><h2>Preparing for LAVA development<a class="headerlink" href="#preparing-for-lava-development" title="Permalink to this heading">¶</a></h2>
<p>LAVA provides a <code class="docutils literal notranslate"><span class="pre">lava-dev</span></code> package which supplies all the dependencies which
are required <a class="reference internal" href="#dev-builds"><span class="std std-ref">to build local LAVA packages</span></a>. This package is
intended primarily for developers working on laptops and other systems where
a full desktop environment is already installed:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo apt install lava-dev
</pre></div>
</div>
<p>If you want to build local packages on a headless box or a system with limited
space, you can trim the set of dependencies by pre-installing
<code class="docutils literal notranslate"><span class="pre">pinentry-curses</span></code> instead of the default <code class="docutils literal notranslate"><span class="pre">pinentry-gtk2</span></code>. QEMU is still
required and will bring in some X11 dependencies but these are minimal compared
to the full dependencies of <code class="docutils literal notranslate"><span class="pre">pinentry-gtk2</span></code> which is brought in via
<code class="docutils literal notranslate"><span class="pre">gnupg2</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo apt install pinentry-curses
$ sudo apt-get --purge remove pinentry-gtk2
$ sudo apt-get --purge autoremove
$ sudo apt install lava-dev
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="development-intro.html#unit-test-dependencies"><span class="std std-ref">Dependencies required to run unit tests</span></a></p>
</div>
</section>
<section id="developer-package-build">
<span id="dev-builds"></span><span id="index-3"></span><h2>Developer package build<a class="headerlink" href="#developer-package-build" title="Permalink to this heading">¶</a></h2>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="#developer-preparations"><span class="std std-ref">Preparing for LAVA development</span></a> and
<a class="reference internal" href="contribution.html#development-pre-requisites"><span class="std std-ref">Pre-requisites to start with development</span></a></p>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The supported suite for LAVA development is now Buster. The
developer package build now defaults to expecting Buster and
therefore uses Python3 exclusively. Support for building Python2 has
been removed, the <code class="docutils literal notranslate"><span class="pre">master</span></code> branch only builds Python3. See
<a class="reference external" href="https://lists.lavasoftware.org/archives/list/lava-announce&#64;lists.lavasoftware.org/thread/KWEPRA5P2LGVZ6WPIBWCYLC3G6TD5SN6/">https://lists.lavasoftware.org/archives/list/lava-announce&#64;lists.lavasoftware.org/thread/KWEPRA5P2LGVZ6WPIBWCYLC3G6TD5SN6/</a></p>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">lava-dev</span></code> package includes a helper script which is also present
in the source code in <code class="docutils literal notranslate"><span class="pre">lava-server/share/</span></code>. The script requires a
normal Debian package build environment (i.e. <code class="docutils literal notranslate"><span class="pre">dpkg-dev</span></code>), the
<code class="docutils literal notranslate"><span class="pre">git-buildpackage</span></code> helper and the build-dependencies of the package
itself. The helper checks for package dependencies using
<code class="docutils literal notranslate"><span class="pre">dpkg-checkbuilddeps</span></code> which halts upon failure with a message showing
which packages need to be installed.</p>
<section id="changes-from-2018-10-onwards">
<h3>Changes from 2018.10 onwards<a class="headerlink" href="#changes-from-2018-10-onwards" title="Permalink to this heading">¶</a></h3>
<ul class="simple">
<li><p>the Debian packaging files are now included upstream, so merge
requests can include changes to the packaging directly. The helper
script converts the package to a “native” package to allow for
unreleased changes.</p></li>
<li><p><strong>ALL</strong> local changes must be committed to a local branch before
attempting a build - the helper will fail with an error if
<code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">ls-files</span> <span class="pre">-m</span> <span class="pre">-o</span> <span class="pre">--exclude-standard</span></code> reports any output.</p></li>
<li><p>Builds are executed in a temporary scratch branch called
<code class="docutils literal notranslate"><span class="pre">lavadevscratch</span></code> which is based on the current local branch and
which is deleted at the end of the operation. This is required so
that the packaging can be temporarily switched to a developer build.</p></li>
<li><p>The helper script no longer accepts the <code class="docutils literal notranslate"><span class="pre">-p</span></code> option, the name
of the package is determined from the upstream Debian packaging.</p></li>
<li><p>The helper script not longer accepts the <code class="docutils literal notranslate"><span class="pre">-b</span></code> option to change
the packaging branch as the packaging is now part of the same
branch as the build.</p></li>
</ul>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ /usr/share/lava-server/debian-dev-build.sh
</pre></div>
</div>
<p>From time to time, dependencies may need to vary between the current Debian
stable release and the unstable suite and the package building tools expect
to build for unstable. If you are building a package to update an instance
running a different suite, pass that suite using the <code class="docutils literal notranslate"><span class="pre">-s</span></code> option:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./share/debian-dev-build.sh -s buster
</pre></div>
</div>
<p>By default, the packages will be built in the <code class="docutils literal notranslate"><span class="pre">../build-area/</span></code>
directory, this can be changed with the <code class="docutils literal notranslate"><span class="pre">-o</span></code> option. Packages are
build using a version string based on the output of <code class="docutils literal notranslate"><span class="pre">./lava_common/version.py</span></code>,
except that hyphens <code class="docutils literal notranslate"><span class="pre">-</span></code> are replaced with period <code class="docutils literal notranslate"><span class="pre">.</span></code> to comply with
the rules for a native Debian package. The helper script outputs the
relative location of all the files generated by the build at the end of
a successful build, ready for use with <code class="docutils literal notranslate"><span class="pre">$</span> <span class="pre">sudo</span> <span class="pre">dpkg</span> <span class="pre">-i</span>
<span class="pre">&lt;path_to_dot_deb_file&gt;</span></code>, repeated for every file or <code class="docutils literal notranslate"><span class="pre">$</span> <span class="pre">sudo</span> <span class="pre">debi</span> <span class="pre">-u</span>
<span class="pre">&lt;path_to_lava_dot_changes_file&gt;</span></code> which will upgrade matching packages
which are already installed but skip ones which are not installed.
e.g.:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ sudo dpkg -i ../build-area/lava-common_2018.7-15-g64824c402-1_all.deb
$ sudo dpkg -i ../build-area/lava-dispatcher_2018.7-15-g64824c402-1_amd64.deb
...
</pre></div>
</div>
<p>or all in one command:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ sudo debi -u ../build-area/lava_2018.7-15-g64824c402-1_amd64.changes
</pre></div>
</div>
<p>To install any package, including the developer build packages, the
corresponding package <strong>must</strong> already be installed at the current production
release version (or better), on the same machine. This ensures that all of the
runtime dependencies already exist on the system.</p>
</section>
<section id="which-branch-to-use-for-changes">
<span id="devel-branches"></span><h3>Which branch to use for changes<a class="headerlink" href="#which-branch-to-use-for-changes" title="Permalink to this heading">¶</a></h3>
<p>Any and all changes for inclusion into a future release need to be based on the
current git master branch and will need rebasing from time to time as master
moves ahead.</p>
<p>All testing of the LAVA source code is based on the relevant master branch
which is then merged into the staging branch for testing as a release
candidate. The final release involves merging staging into the release branch.
Git tags are based on the release branch.</p>
<p>When using existing git tags or the release branch, create a new local branch
and commit your changes to ensure that a <a class="reference internal" href="#local-version-strings"><span class="std std-ref">local version string</span></a> is used.</p>
<p>There can also be new dependencies added by changes in master and
staging before those changes are merged into release or uploaded as
a production release. When these changes are merged into master, the
packaging will also be updated.</p>
</section>
<section id="local-version-strings">
<span id="id1"></span><h3>Local version strings<a class="headerlink" href="#local-version-strings" title="Permalink to this heading">¶</a></h3>
<p>The local version is built (using <code class="docutils literal notranslate"><span class="pre">./lava_common/version.py</span></code>) from these components:</p>
<ul>
<li><p>package name</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">git</span> <span class="pre">describe</span></code> - (dashes replaced by dots):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./lava_common/version.py
2018.7.35.gb022cde9
</pre></div>
</div>
</li>
</ul>
<p>The latest git hash is a reference to the latest commit. If you have
not committed local changes (e.g. you are on a local branch based on a
tag) then the short hash can be used to lookup the commit in the master
branch, omitting the <code class="docutils literal notranslate"><span class="pre">g</span></code> prefix, e.g.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">gitlab</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">lava</span><span class="o">/</span><span class="n">lava</span><span class="o">/</span><span class="n">commit</span><span class="o">/</span><span class="n">b022cde9</span>
</pre></div>
</div>
</section>
<section id="distribution-differences">
<span id="id2"></span><h3>Distribution differences<a class="headerlink" href="#distribution-differences" title="Permalink to this heading">¶</a></h3>
<p><strong>Always</strong> build packages on the suite you expect to use for installation.</p>
<p>Packages available from the <a class="reference internal" href="installing_on_debian.html#lava-repositories"><span class="std std-ref">LAVA repositories</span></a> are built on
the correct suite (using sbuild) using the <a class="reference external" href="https://git.linaro.org/lava/lava-buildd.git">lava-buildd scripts</a>.</p>
</section>
<section id="example">
<h3>Example<a class="headerlink" href="#example" title="Permalink to this heading">¶</a></h3>
<p>The helper supports <code class="docutils literal notranslate"><span class="pre">lava</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo apt install lava-dev
$ git clone https://gitlab.com/lava/lava.git
$ cd lava
$ ./share/debian-dev-build.sh
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">lava-dispatcher</span></code> has architecture-dependent dependencies. By
default, the package is built for the native architecture and can only
be installed on that architecture. To build for a different
architecture, e.g. arm64, use:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ /usr/share/lava-server/debian-dev-build.sh -a arm64 -B
</pre></div>
</div>
<p>This does a <em>binary build</em>, so the source is not included, which allows
these builds to be included in a local repository, e.g. using
<code class="docutils literal notranslate"><span class="pre">reprepro</span></code>.</p>
<p>Helpers for other distributions may be added in due course. Patches
welcome.</p>
</section>
<section id="developer-build-versions">
<span id="developer-build-version"></span><h3>Developer build versions<a class="headerlink" href="#developer-build-versions" title="Permalink to this heading">¶</a></h3>
<p>LAVA uses git tags and the developer build adds a suffix to the tag for
each local build - the suffix is formed from the output of <code class="docutils literal notranslate"><span class="pre">git</span>
<span class="pre">describe</span></code></p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="#local-version-strings"><span class="std std-ref">Local version strings</span></a> for information on how to
look up the commit information from the version string.</p>
</div>
<p>From August 2015, LAVA uses git tags without a leading zero on the
month number, in accordance with PEP440, so the git tag will be
<code class="docutils literal notranslate"><span class="pre">2015.8</span></code> instead of <code class="docutils literal notranslate"><span class="pre">2015.07</span></code> used for the previous release tag.</p>
</section>
</section>
<section id="development-using-python3">
<span id="developer-python3"></span><span id="index-4"></span><h2>Development using Python3<a class="headerlink" href="#development-using-python3" title="Permalink to this heading">¶</a></h2>
<p>LAVA has moved to exclusive Python3 support as the final stage of the
migration to V2. See
<a class="reference external" href="https://lists.lavasoftware.org/archives/list/lava-announce&#64;lists.lavasoftware.org/thread/6QEDKDIQ2GFEPK5SRIE36RV234NSLSB6/">https://lists.lavasoftware.org/archives/list/lava-announce&#64;lists.lavasoftware.org/thread/6QEDKDIQ2GFEPK5SRIE36RV234NSLSB6/</a></p>
<p>Both lava-server and lava-dispatcher only support running the unit tests with
Python3. <strong>All</strong> reviews <strong>must</strong> pass the unit tests when run with Python3.</p>
<p>Builds for Debian Jessie have ceased, support for Python2 has been dropped and
<strong>only</strong> Python3 is be supported.</p>
<p>Python3 and other dependencies are tracked using files in
<code class="docutils literal notranslate"><span class="pre">share/requirements</span></code> using the <code class="docutils literal notranslate"><span class="pre">./share/requires.py</span></code> script.
Required arguments are:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>-d, --distribution    Name of a distribution directory in ./share/requirements
-s, --suite           Name of a suite in the specified distribution directory
-p, --package         A LAVA package name in the distribution and suite
</pre></div>
</div>
<p>Optional arguments are:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>-n, --names           List the distribution package names
-u, --unittests       Distribution package names for unittest support -
                      requires --names
</pre></div>
</div>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>./share/requires.py --distribution debian --suite buster --package lava-dispatcher --names
python3-configobj python3-guestfs python3-jinja2 python3-magic
python3-netifaces python3-pexpect python3-pyudev
python3-requests python3-setproctitle python3-tz python3-yaml
python3-zmq
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="development-intro.html#developer-workflow"><span class="std std-ref">Developer workflows</span></a> and <a class="reference internal" href="development.html#running-black"><span class="std std-ref">Source code formatting</span></a></p>
</div>
</section>
<section id="quick-fixes-and-testing">
<span id="quick-fixes"></span><h2>Quick fixes and testing<a class="headerlink" href="#quick-fixes-and-testing" title="Permalink to this heading">¶</a></h2>
<p>The paths to execute LAVA python scripts and run unit tests have
changed and developing LAVA based on packages has a different workflow.</p>
<p>Modified files can be copied to the equivalent python path. The current LAVA
packages use python3, so the path is beneath
<code class="docutils literal notranslate"><span class="pre">/usr/lib/python3/dist-packages/</span></code> with sudo:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo cp &lt;git-path&gt; /usr/lib/python3/dist-packages/&lt;git-path&gt;
</pre></div>
</div>
</section>
<section id="viewing-changes">
<h2>Viewing changes<a class="headerlink" href="#viewing-changes" title="Permalink to this heading">¶</a></h2>
<p>Different actions are needed for local changes to take effect, depending on the
type of file(s) updated:</p>
<table class="docutils align-default">
<tbody>
<tr class="row-odd"><td><p>templates/*/*.html</p></td>
<td><p>next browser refresh (F5/Ctrl-R)</p></td>
</tr>
<tr class="row-even"><td><p>device-types/*.jinja2</p></td>
<td><p>next testjob submission</p></td>
</tr>
<tr class="row-odd"><td><p>devices/*.jinja2</p></td>
<td><p>next testjob submission</p></td>
</tr>
<tr class="row-even"><td><p>*_app/*.py</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">$</span> <span class="pre">sudo</span> <span class="pre">apache2ctl</span> <span class="pre">restart</span></code></p></td>
</tr>
</tbody>
</table>
</section>
<section id="migrating-postgresql-versions">
<span id="index-5"></span><span id="id3"></span><h2>Migrating postgresql versions<a class="headerlink" href="#migrating-postgresql-versions" title="Permalink to this heading">¶</a></h2>
<p>LAVA installs the <code class="docutils literal notranslate"><span class="pre">postgresql</span></code> package which installs the current default
version of postgresql. When this default changes in Debian, a second package
will be added to your system which will start with no actual data.</p>
<div class="admonition caution">
<p class="admonition-title">Caution</p>
<p><code class="docutils literal notranslate"><span class="pre">postgresql</span></code> <strong>will disable database access</strong> during the
migration and this will interfere with the running instance. There is
typically no rush to do the migration, so this is usually a task for a
scheduled maintenance window. Declare a time when all devices can be taken
offline and put a replacement site in place of the apache configuration to
prevent database access during the migration.</p>
</div>
<section id="determining-the-active-cluster">
<h3>Determining the active cluster<a class="headerlink" href="#determining-the-active-cluster" title="Permalink to this heading">¶</a></h3>
<p>The output of <code class="docutils literal notranslate"><span class="pre">pg_lsclusters</span></code> includes the port number of each cluster.
To ensure that the correct cluster is upgraded, check the <code class="docutils literal notranslate"><span class="pre">LAVA_DB_PORT</span></code>
setting in <code class="docutils literal notranslate"><span class="pre">/etc/lava-server/instance.conf</span></code> for the current instance. If
multiple clusters are shown, <code class="docutils literal notranslate"><span class="pre">postgresql</span></code> will upgrade to the latest version,
so ensure that any intermediate clusters are also stopped before starting the
migration.</p>
</section>
<section id="performing-the-migration">
<h3>Performing the migration<a class="headerlink" href="#performing-the-migration" title="Permalink to this heading">¶</a></h3>
<p>Debian gives a notice similar to this when a new version of postgres is
installed or the old one is obsolete:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Obsolete major version 13

The PostgreSQL version 13 is obsolete, but the server or client packages
are still installed. Please install the latest packages
(postgresql-15 and postgresql-client-15) and upgrade the existing
clusters with pg_upgradecluster (see manpage).

Please be aware that the installation of posgresql-15 will automatically
create a default cluster 15/main. If you want to upgrade the 13/main cluster,
you need to remove the already existing 15 cluster (pg_dropcluster --stop
15 main, see manpage for details).

The old server and client packages are no longer supported. After the
existingt clusters are upgraded, the postgresql-13 and postgresql-client-13
packages should be removed.

Please see /usr/share/doc/posgresql-common/README.Debian.gz for details.
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Upgrading a cluster combines <code class="docutils literal notranslate"><span class="pre">pg_dump</span></code> and <code class="docutils literal notranslate"><span class="pre">pg_restore</span></code> (making
two copies of the database at one point). Ensure that you have enough
available space on the disc, especially with a large database. If
<code class="docutils literal notranslate"><span class="pre">pg_upgradecluster</span></code> is interrupted by the lack of disc space it will
not harm the system and full rollback will be applied automatically.</p>
</div>
<p>See also
<a class="reference external" href="https://www.postgresql.org/docs/current/pgupgrade.html#id-1.9.5.12.7">https://www.postgresql.org/docs/current/pgupgrade.html#id-1.9.5.12.7</a></p>
<p>Check your existing clusters:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo pg_lsclusters
</pre></div>
</div>
<p>Stop postgresql (stops both versions):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo service postgresql stop
</pre></div>
</div>
<p>Drop the <strong>main</strong> cluster of the <strong>NEW</strong> postgres as this is empty:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo pg_dropcluster 15 main --stop
</pre></div>
</div>
<p>Postgresql knows which version is the current default, so just tell postgresql
which is the old version to migrate the data into the (empty) new one:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># sudo pg_upgradecluster 13 main</span>
<span class="n">Restarting</span> <span class="n">old</span> <span class="n">cluster</span> <span class="k">with</span> <span class="n">restricted</span> <span class="n">connections</span><span class="o">...</span>
<span class="n">Notice</span><span class="p">:</span> <span class="n">extra</span> <span class="n">pg_ctl</span><span class="o">/</span><span class="n">postgres</span> <span class="n">options</span> <span class="n">given</span><span class="p">,</span> <span class="n">bypassing</span> <span class="n">systemctl</span> <span class="k">for</span> <span class="n">start</span> <span class="n">operation</span>
<span class="n">Creating</span> <span class="n">new</span> <span class="n">PostgreSQL</span> <span class="n">cluster</span> <span class="mi">15</span><span class="o">/</span><span class="n">main</span> <span class="o">...</span>
<span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">15</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">initdb</span> <span class="o">-</span><span class="n">D</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">15</span><span class="o">/</span><span class="n">main</span> <span class="o">--</span><span class="n">auth</span><span class="o">-</span><span class="n">local</span> <span class="n">peer</span> <span class="o">--</span><span class="n">auth</span><span class="o">-</span><span class="n">host</span> <span class="n">scram</span><span class="o">-</span><span class="n">sha</span><span class="o">-</span><span class="mi">256</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">instructions</span> <span class="o">--</span><span class="n">encoding</span> <span class="n">UTF8</span> <span class="o">--</span><span class="n">lc</span><span class="o">-</span><span class="n">collate</span> <span class="n">en_US</span><span class="o">.</span><span class="n">UTF</span><span class="o">-</span><span class="mi">8</span> <span class="o">--</span><span class="n">lc</span><span class="o">-</span><span class="n">ctype</span> <span class="n">en_US</span><span class="o">.</span><span class="n">UTF</span><span class="o">-</span><span class="mi">8</span>
<span class="n">The</span> <span class="n">files</span> <span class="n">belonging</span> <span class="n">to</span> <span class="n">this</span> <span class="n">database</span> <span class="n">system</span> <span class="n">will</span> <span class="n">be</span> <span class="n">owned</span> <span class="n">by</span> <span class="n">user</span> <span class="s2">&quot;postgres&quot;</span><span class="o">.</span>
<span class="n">This</span> <span class="n">user</span> <span class="n">must</span> <span class="n">also</span> <span class="n">own</span> <span class="n">the</span> <span class="n">server</span> <span class="n">process</span><span class="o">.</span>

<span class="n">The</span> <span class="n">database</span> <span class="n">cluster</span> <span class="n">will</span> <span class="n">be</span> <span class="n">initialized</span> <span class="k">with</span> <span class="n">locale</span> <span class="s2">&quot;en_US.UTF-8&quot;</span><span class="o">.</span>
<span class="n">The</span> <span class="n">default</span> <span class="n">text</span> <span class="n">search</span> <span class="n">configuration</span> <span class="n">will</span> <span class="n">be</span> <span class="nb">set</span> <span class="n">to</span> <span class="s2">&quot;english&quot;</span><span class="o">.</span>

<span class="n">Data</span> <span class="n">page</span> <span class="n">checksums</span> <span class="n">are</span> <span class="n">disabled</span><span class="o">.</span>

<span class="n">fixing</span> <span class="n">permissions</span> <span class="n">on</span> <span class="n">existing</span> <span class="n">directory</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">15</span><span class="o">/</span><span class="n">main</span> <span class="o">...</span> <span class="n">ok</span>
<span class="n">creating</span> <span class="n">subdirectories</span> <span class="o">...</span> <span class="n">ok</span>
<span class="n">selecting</span> <span class="n">dynamic</span> <span class="n">shared</span> <span class="n">memory</span> <span class="n">implementation</span> <span class="o">...</span> <span class="n">posix</span>
<span class="n">selecting</span> <span class="n">default</span> <span class="n">max_connections</span> <span class="o">...</span> <span class="mi">100</span>
<span class="n">selecting</span> <span class="n">default</span> <span class="n">shared_buffers</span> <span class="o">...</span> <span class="mi">128</span><span class="n">MB</span>
<span class="n">selecting</span> <span class="n">default</span> <span class="n">time</span> <span class="n">zone</span> <span class="o">...</span> <span class="n">Europe</span><span class="o">/</span><span class="n">Berlin</span>
<span class="n">creating</span> <span class="n">configuration</span> <span class="n">files</span> <span class="o">...</span> <span class="n">ok</span>
<span class="n">running</span> <span class="n">bootstrap</span> <span class="n">script</span> <span class="o">...</span> <span class="n">ok</span>
<span class="n">performing</span> <span class="n">post</span><span class="o">-</span><span class="n">bootstrap</span> <span class="n">initialization</span> <span class="o">...</span> <span class="n">ok</span>
<span class="n">syncing</span> <span class="n">data</span> <span class="n">to</span> <span class="n">disk</span> <span class="o">...</span> <span class="n">ok</span>

<span class="n">Copying</span> <span class="n">old</span> <span class="n">configuration</span> <span class="n">files</span><span class="o">...</span>
<span class="n">Copying</span> <span class="n">old</span> <span class="n">start</span><span class="o">.</span><span class="n">conf</span><span class="o">...</span>
<span class="n">Copying</span> <span class="n">old</span> <span class="n">pg_ctl</span><span class="o">.</span><span class="n">conf</span><span class="o">...</span>
<span class="n">Starting</span> <span class="n">new</span> <span class="n">cluster</span><span class="o">...</span>
<span class="n">Notice</span><span class="p">:</span> <span class="n">extra</span> <span class="n">pg_ctl</span><span class="o">/</span><span class="n">postgres</span> <span class="n">options</span> <span class="n">given</span><span class="p">,</span> <span class="n">bypassing</span> <span class="n">systemctl</span> <span class="k">for</span> <span class="n">start</span> <span class="n">operation</span>
<span class="n">Roles</span><span class="p">,</span> <span class="n">databases</span><span class="p">,</span> <span class="n">schemas</span><span class="p">,</span> <span class="n">ACLs</span><span class="o">...</span>
 <span class="n">set_config</span>
<span class="o">------------</span>

<span class="p">(</span><span class="mi">1</span> <span class="n">row</span><span class="p">)</span>

<span class="p">[</span><span class="o">...</span><span class="p">]</span>

<span class="n">Fixing</span> <span class="n">hardcoded</span> <span class="n">library</span> <span class="n">paths</span> <span class="k">for</span> <span class="n">stored</span> <span class="n">procedures</span><span class="o">...</span>
<span class="n">Upgrading</span> <span class="n">database</span> <span class="n">devel</span><span class="o">...</span>
<span class="n">Analyzing</span> <span class="n">database</span> <span class="n">devel</span><span class="o">...</span>
<span class="n">Fixing</span> <span class="n">hardcoded</span> <span class="n">library</span> <span class="n">paths</span> <span class="k">for</span> <span class="n">stored</span> <span class="n">procedures</span><span class="o">...</span>
<span class="n">Upgrading</span> <span class="n">database</span> <span class="n">template1</span><span class="o">...</span>
<span class="n">Analyzing</span> <span class="n">database</span> <span class="n">template1</span><span class="o">...</span>
<span class="n">Fixing</span> <span class="n">hardcoded</span> <span class="n">library</span> <span class="n">paths</span> <span class="k">for</span> <span class="n">stored</span> <span class="n">procedures</span><span class="o">...</span>
<span class="n">Upgrading</span> <span class="n">database</span> <span class="n">lavaserver</span><span class="o">...</span>
<span class="n">Analyzing</span> <span class="n">database</span> <span class="n">lavaserver</span><span class="o">...</span>
<span class="n">Fixing</span> <span class="n">hardcoded</span> <span class="n">library</span> <span class="n">paths</span> <span class="k">for</span> <span class="n">stored</span> <span class="n">procedures</span><span class="o">...</span>
<span class="n">Upgrading</span> <span class="n">database</span> <span class="n">postgres</span><span class="o">...</span>
<span class="n">Analyzing</span> <span class="n">database</span> <span class="n">postgres</span><span class="o">...</span>
<span class="n">Stopping</span> <span class="n">target</span> <span class="n">cluster</span><span class="o">...</span>
<span class="n">Stopping</span> <span class="n">old</span> <span class="n">cluster</span><span class="o">...</span>
<span class="n">Disabling</span> <span class="n">automatic</span> <span class="n">startup</span> <span class="n">of</span> <span class="n">old</span> <span class="n">cluster</span><span class="o">...</span>

<span class="n">Success</span><span class="o">.</span> <span class="n">Please</span> <span class="n">check</span> <span class="n">that</span> <span class="n">the</span> <span class="n">upgraded</span> <span class="n">cluster</span> <span class="n">works</span><span class="o">.</span> <span class="n">If</span> <span class="n">it</span> <span class="n">does</span><span class="p">,</span>
<span class="n">you</span> <span class="n">can</span> <span class="n">remove</span> <span class="n">the</span> <span class="n">old</span> <span class="n">cluster</span> <span class="k">with</span>
    <span class="n">pg_dropcluster</span> <span class="mi">13</span> <span class="n">main</span>

<span class="n">Ver</span> <span class="n">Cluster</span> <span class="n">Port</span> <span class="n">Status</span> <span class="n">Owner</span>    <span class="n">Data</span> <span class="n">directory</span>              <span class="n">Log</span> <span class="n">file</span>
<span class="mi">13</span>  <span class="n">main</span>    <span class="mi">5433</span> <span class="n">down</span>   <span class="n">postgres</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">13</span><span class="o">/</span><span class="n">main</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">log</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="n">postgresql</span><span class="o">-</span><span class="mi">13</span><span class="o">-</span><span class="n">main</span><span class="o">.</span><span class="n">log</span>
<span class="n">Ver</span> <span class="n">Cluster</span> <span class="n">Port</span> <span class="n">Status</span> <span class="n">Owner</span>    <span class="n">Data</span> <span class="n">directory</span>              <span class="n">Log</span> <span class="n">file</span>
<span class="mi">15</span>  <span class="n">main</span>    <span class="mi">5432</span> <span class="n">down</span>   <span class="n">postgres</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">15</span><span class="o">/</span><span class="n">main</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">log</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="n">postgresql</span><span class="o">-</span><span class="mi">15</span><span class="o">-</span><span class="n">main</span><span class="o">.</span><span class="n">log</span>
</pre></div>
</div>
<p>Restart postgresql (starts the new version):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo service postgresql start
</pre></div>
</div>
<p>Check that the instance is still running. Note that the port of the new
postgresql server will have been upgraded to the port used for the old
postgresql server automatically. Check that this is the case:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># sudo pg_lsclusters</span>
<span class="n">Ver</span> <span class="n">Cluster</span> <span class="n">Port</span> <span class="n">Status</span> <span class="n">Owner</span>    <span class="n">Data</span> <span class="n">directory</span>              <span class="n">Log</span> <span class="n">file</span>
<span class="mi">13</span>  <span class="n">main</span>    <span class="mi">5433</span> <span class="n">down</span>   <span class="n">postgres</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">13</span><span class="o">/</span><span class="n">main</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">log</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="n">postgresql</span><span class="o">-</span><span class="mi">13</span><span class="o">-</span><span class="n">main</span><span class="o">.</span><span class="n">log</span>
<span class="mi">15</span>  <span class="n">main</span>    <span class="mi">5432</span> <span class="n">online</span> <span class="n">postgres</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="mi">15</span><span class="o">/</span><span class="n">main</span> <span class="o">/</span><span class="n">var</span><span class="o">/</span><span class="n">log</span><span class="o">/</span><span class="n">postgresql</span><span class="o">/</span><span class="n">postgresql</span><span class="o">-</span><span class="mi">15</span><span class="o">-</span><span class="n">main</span><span class="o">.</span><span class="n">log</span>
</pre></div>
</div>
<p>Drop the old cluster:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo pg_dropcluster 13 main
</pre></div>
</div>
<p>Now the old database package can be removed:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ sudo apt remove postgresql-13
</pre></div>
</div>
</section>
</section>
<section id="dependency-requirements">
<span id="index-6"></span><span id="id4"></span><h2>Dependency Requirements<a class="headerlink" href="#dependency-requirements" title="Permalink to this heading">¶</a></h2>
<p>LAVA needs to control and output the list of dependencies in a variety
of formats. Building Docker images and running unit tests in an LXC
need an updated list of binary package names suitable for the
distribution and suite of the LXC. Each needs to cope with dependencies
outside the specified suite, e.g. stable releases which need backports.
Building the LAVA Debian packages themselves also requires a properly
up to date list of dependencies - including minimum versions. Each set
of dependencies needs to be specific to each LAVA binary package -
<code class="docutils literal notranslate"><span class="pre">lava-server</span></code> has different dependencies to <code class="docutils literal notranslate"><span class="pre">lava-dispatcher</span></code> and
<code class="docutils literal notranslate"><span class="pre">lava-common</span></code>.</p>
<p>LAVA has several dependencies which are not available via PyPi or pip
and the <code class="docutils literal notranslate"><span class="pre">requirements.txt</span></code> file is therefore misleading. However, the
format of this file is still useful in building the LAVA packages.</p>
<p>Therefore, LAVA has the <code class="docutils literal notranslate"><span class="pre">./share/requires.py</span></code> script which can be
used to output the preferred format, depending on the arguments. The
script is also included in the <code class="docutils literal notranslate"><span class="pre">lava-dev</span></code> package as
<code class="docutils literal notranslate"><span class="pre">/usr/share/lava-server/requires.py</span></code>.</p>
<p>The dependencies <strong>MUST</strong> be installed in the specified release of the
specified distribution for LAVA to work, so take care before pushing a
merge request to add package names to the support. Make sure your merge
request includes a change to the relevant requirement YAML files for
<strong>all</strong> supported distributions or the CI will fail.</p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="development-intro.html#developer-workflow"><span class="std std-ref">Developer workflows</span></a></p>
</div>
<p>Some distributions support <code class="docutils literal notranslate"><span class="pre">Recommends</span></code> level dependencies. These are
typically intended to be installed by ~90% of installations but give
flexibility for other use cases. <code class="docutils literal notranslate"><span class="pre">Recommends</span></code> are <strong>not</strong> handled by
<code class="docutils literal notranslate"><span class="pre">requires.py</span></code> at all. The packages must be listed explicitly by the
maintainer of the packaging for the distribution. <code class="docutils literal notranslate"><span class="pre">requires.py</span></code>
exists so that automated processes, like CI, can have a reliable but
minimal set of packages which must be installed for the specified
package to be installable. To use a minimal installation, each package
listed by <cite>./share/requires.py`</cite> can be installed without its
recommended packages using the <code class="docutils literal notranslate"><span class="pre">apt</span> <span class="pre">install</span> <span class="pre">--no-install-recommends</span>
<span class="pre">&lt;packages&gt;</span></code> syntax.</p>
<p><code class="docutils literal notranslate"><span class="pre">requires.py</span></code> does not currently support dependencies based on the
architecture of the installation. (Currently, only <code class="docutils literal notranslate"><span class="pre">Recommends</span></code>
includes architecture-sensitive packages.)</p>
<section id="outputting-the-requirements-txt-format">
<h3>Outputting the requirements.txt format<a class="headerlink" href="#outputting-the-requirements-txt-format" title="Permalink to this heading">¶</a></h3>
<p>Processes which need the version string can use the original output
format which mimics <code class="docutils literal notranslate"><span class="pre">requirements.txt</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./share/requires.py --package lava-server --distribution debian --suite buster
django&gt;=1.10
PyYAML
docutils&gt;=0.6
jinja2
psycopg2
pytz
pyzmq
requests
voluptuous&gt;=0.8.8
</pre></div>
</div>
</section>
<section id="outputting-a-list-of-binary-package-names">
<h3>Outputting a list of binary package names<a class="headerlink" href="#outputting-a-list-of-binary-package-names" title="Permalink to this heading">¶</a></h3>
<p>This is intended to be passed directly to a package installer like
<code class="docutils literal notranslate"><span class="pre">apt-get</span></code> together with the other required commands and options.</p>
<p>The caller determines the <code class="docutils literal notranslate"><span class="pre">suite</span></code>, so to use with buster-backports,
the <code class="docutils literal notranslate"><span class="pre">-t</span> <span class="pre">buster-backports</span></code> option would also be added to the
other <code class="docutils literal notranslate"><span class="pre">apt-get</span></code> commands before appending the list of packages.</p>
<p>(Line breaks are added for readability only):</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ ./share/requires.py --package lava-server --distribution debian --suite buster --names
python3-django python3-yaml python3-docutils \
python3-jinja2 python3-psycopg2 python3-tz python3-zmq python3-requests \
python3-voluptuous
</pre></div>
</div>
</section>
<section id="adding-packages-needed-for-the-unittests">
<h3>Adding packages needed for the unittests<a class="headerlink" href="#adding-packages-needed-for-the-unittests" title="Permalink to this heading">¶</a></h3>
<p>Some packages are only required to allow the unittests to pass. To add
these packages, use the <code class="docutils literal notranslate"><span class="pre">--unittest</span></code> option, in combination with
<code class="docutils literal notranslate"><span class="pre">--names</span></code>. These packages need to be added to the installation as
well as the base list of packages using <code class="docutils literal notranslate"><span class="pre">--names</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./share/requires.py --package lava-server --distribution debian --suite unstable --names --unittest
python3-pytest-django python3-pytest python3-pytest-cov
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./share/requires.py --package lava-dispatcher --distribution debian --suite unstable --names --unittest
pyocd-flashtool gdb-multiarch git schroot lxc img2simg simg2img u-boot-tools docker.io xnbd-server telnet qemu-system-x86 qemu-system-arm
</pre></div>
</div>
</section>
</section>
<section id="javascript-handling">
<span id="index-7"></span><span id="id5"></span><h2>Javascript handling<a class="headerlink" href="#javascript-handling" title="Permalink to this heading">¶</a></h2>
<p>Javascript has particular issues in distributions, often the version of a
Javascript file is out of step with the version available in the distribution
or not packaged at all. <code class="docutils literal notranslate"><span class="pre">lava-server</span></code> embeds javascript files in the
<code class="docutils literal notranslate"><span class="pre">static/js</span></code> directories and maintains a list of files which are replaced with
symlinks during a Debian package build. The list is in
<code class="file docutils literal notranslate"><span class="pre">share/javascript.yaml</span></code> and the replacement of matching files is done
using <code class="file docutils literal notranslate"><span class="pre">share/javascript.py</span></code>. Other distribution builds are invited to use
the same script or provide patches if the paths within the script need
modification.</p>
<p>After 2015.12 release, all of the .min.js files in the package are removed from
VCS and minified files are created at build time. Templates in the system use
only minified versions of the javascript files so after the release package
rebuild will be mandatory.</p>
<section id="javascript-and-security">
<span id="javascript-security"></span><h3>Javascript and security<a class="headerlink" href="#javascript-and-security" title="Permalink to this heading">¶</a></h3>
<p>The primary concern is security fixes. Distributions release with a particular
release of LAVA and may need to fix security problems in that release. If the
file is replaced by a symlink to an external package in the distribution, then
the security problem and fix migrate to that package. LAVA tracks these files
in <code class="file docutils literal notranslate"><span class="pre">share/javascript.yaml</span></code>. Files which only exist in LAVA or exist at a
different version to the one available in the distribution, need to be patched
within LAVA. Javascript files created by LAVA are packaged as editable source
code and patches to these files will take effect in LAVA after a simple restart
of apache and a clearing of any browser cache. Problems arise when the
javascript files in the LAVA source code have been <a class="reference external" href="https://en.wikipedia.org/wiki/Minification_(programming)">minified</a>, resulting in a
<code class="file docutils literal notranslate"><span class="pre">.min.js</span></code> file which is <strong>not</strong> suitable for editing or patching.</p>
<p>The source code for the minified JS used in LAVA is provided in the LAVA source
code, alongside the minified version. <strong>However</strong>, there is a lack of suitable
tools to convert changes to the source file into a comparable minified file. If
these files need changes, the correct fix would be to patch the unminified
javascript and copy the modified file over the top of the minified version.
This loses the advantages of minification but gains the benefit of a known
security fix.</p>
</section>
<section id="javascript-maintenance">
<span id="id6"></span><h3>Javascript maintenance<a class="headerlink" href="#javascript-maintenance" title="Permalink to this heading">¶</a></h3>
<p>Work is ongoing upstream to resolve the remaining minified javascript
files:</p>
<ol class="arabic simple">
<li><p><strong>Identify</strong> the upstream location of all javascript not listed in
<code class="file docutils literal notranslate"><span class="pre">share/javascript.yaml</span></code> and not written by LAVA, specify this location
in a <code class="file docutils literal notranslate"><span class="pre">README</span></code> in the relevant <code class="file docutils literal notranslate"><span class="pre">js/</span></code> directory along with
details, if any, of how a modified file can be minified or whether a
modified file should simply replace the minified file.</p></li>
<li><p><strong>Replace</strong> the use of the remaining minified JS where the change to
unminified has a negligible or acceptable performance change. If no upstream
can be identified, LAVA will need to take over maintenance of the javascript
itself, at which point minified files will be dropped until other LAVA
javascript can also be minified.</p></li>
<li><p><strong>Monitor</strong> availability of packages for all javascript files not written by
LAVA and add to the listing in <code class="file docutils literal notranslate"><span class="pre">share/javascript.yaml</span></code> when packages
become available.</p></li>
<li><p><strong>Maintain</strong> - only minify javascript written by LAVA <strong>if</strong> a suitable
minify tool is available to be used during the build of the packages and to
add such support to <code class="file docutils literal notranslate"><span class="pre">share/javascript.py</span></code> so that minification happens
at the same point as replacement of embedded javascript with symlinks to
externally provided files.</p></li>
</ol>
</section>
<section id="packaging-changes">
<span id="testing-packaging"></span><h3>Packaging changes<a class="headerlink" href="#packaging-changes" title="Permalink to this heading">¶</a></h3>
<p>From time to time, there can be packaging changes required to handle changes in
the LAVA upstream codebase. If you have write access to the packaging
repository, changes to the packaging can be tested by pushing to your
fork of lava.git and making a local commit. Then build as normal:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ /usr/share/lava-server/debian-dev-build.sh
</pre></div>
</div>
</section>
<section id="building-for-other-architectures">
<span id="architecture-builds"></span><h3>Building for other architectures<a class="headerlink" href="#building-for-other-architectures" title="Permalink to this heading">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">lava-server</span></code> is the same for all architectures but <code class="docutils literal notranslate"><span class="pre">lava-dispatcher</span></code> has a
different set of dependencies depending on the build architecture. To build an
<code class="docutils literal notranslate"><span class="pre">arm64</span></code> package of lava-dispatcher using the developer scripts, use:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ /usr/share/lava-server/debian-dev-build.sh -a arm64 -B
</pre></div>
</div>
</section>
</section>
<section id="debugging-django-issues">
<span id="django-debug-toolbar"></span><h2>Debugging Django issues<a class="headerlink" href="#debugging-django-issues" title="Permalink to this heading">¶</a></h2>
<p>When trying to investigate LAVA web pages generation we advise you to use
<a class="reference external" href="https://django-debug-toolbar.readthedocs.org">django-debug-toolbar</a>. This is
a Django application that provide more information on how the page was
rendered, including:</p>
<ul class="simple">
<li><p>SQL queries</p></li>
<li><p>templates involved</p></li>
<li><p>HTTP headers</p></li>
</ul>
<p>For instance, the toolbar is a really helpful resource to debug the Django
<abbr title="Object Relational Model">ORM</abbr>.</p>
<section id="installing">
<h3>Installing<a class="headerlink" href="#installing" title="Permalink to this heading">¶</a></h3>
<p>On a Debian system, just run:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ apt-get install python-django-debug-toolbar
</pre></div>
</div>
</section>
<section id="configuration">
<h3>Configuration<a class="headerlink" href="#configuration" title="Permalink to this heading">¶</a></h3>
<p>Once the <code class="docutils literal notranslate"><span class="pre">python-django-debug-toolbar</span></code> package is installed, the toolbar
needs to be enabled in the instance. Two settings are required in
<code class="docutils literal notranslate"><span class="pre">/etc/lava-server/settings.conf</span></code></p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;DEBUG&quot;:</span> <span class="pre">true,</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">&quot;USE_DEBUG_TOOLBAR&quot;:</span> <span class="pre">true,</span></code></p></li>
</ul>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">settings.conf</span></code> is JSON syntax, so ensure that the previous
line ends with a comma and that the resulting file validates as JSON.
Use <a class="reference external" href="https://jsonlint.com">JSONLINT</a></p>
</div>
<p>The toolbar can be disabled without disabling django debug but django must be
in debug mode for the toolbar to be loaded at all.</p>
<p>Restart the <code class="docutils literal notranslate"><span class="pre">django</span></code> related services to complete the installation of the
toolbar:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">service</span> <span class="n">lava</span><span class="o">-</span><span class="n">server</span><span class="o">-</span><span class="n">gunicorn</span> <span class="n">restart</span>
<span class="n">sudo</span> <span class="n">apache2ctl</span> <span class="n">restart</span>
</pre></div>
</div>
<p>Installation can be checked using <code class="docutils literal notranslate"><span class="pre">lava-server</span> <span class="pre">manage</span> <span class="pre">shell</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="gp">&gt;&gt;&gt; </span><span class="s1">&#39;debug_toolbar&#39;</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">INSTALLED_APPS</span>
<span class="go">True</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="development.html#developer-access-to-django-shell"><span class="std std-ref">Developer access to django shell</span></a></p>
</div>
<p>In order to see the toolbar, you should also check the value of <a class="reference external" href="https://docs.djangoproject.com/en/3.2/ref/settings/#internal-ips">INTERNAL_IPS</a>. Local
addresses <code class="docutils literal notranslate"><span class="pre">127.0.0.1</span></code> and <code class="docutils literal notranslate"><span class="pre">::1</span></code> are enabled by default.</p>
<p>To add more addresses, set <code class="docutils literal notranslate"><span class="pre">INTERNAL_IPS</span></code> to a list of addresses in
<code class="docutils literal notranslate"><span class="pre">/etc/lava-server/settings.conf</span></code>, (JSON syntax) for example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s2">&quot;INTERNAL_IPS&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;192.168.0.5&quot;</span><span class="p">,</span> <span class="s2">&quot;10.0.0.6&quot;</span><span class="p">],</span>
</pre></div>
</div>
<p>These value depends on your setup. But if you don’t see the toolbar that’s the
first think to look at.</p>
<p>Apache then needs access to django-debug-toolbar CSS and JS files:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">su</span> <span class="o">-</span>
<span class="n">cd</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">lava</span><span class="o">-</span><span class="n">server</span><span class="o">/</span><span class="n">static</span><span class="o">/</span>
<span class="n">ln</span> <span class="o">-</span><span class="n">s</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">python3</span><span class="o">/</span><span class="n">dist</span><span class="o">-</span><span class="n">packages</span><span class="o">/</span><span class="n">debug_toolbar</span><span class="o">/</span><span class="n">static</span><span class="o">/</span><span class="n">debug_toolbar</span> <span class="o">.</span>
</pre></div>
</div>
<p>In <code class="docutils literal notranslate"><span class="pre">/etc/lava-server/settings.conf</span></code> remove the reference to htdocs in
<code class="docutils literal notranslate"><span class="pre">STATICFILES_DIRS</span></code>. Django-debug-toolbar does check that all directories
listed in <code class="docutils literal notranslate"><span class="pre">STATICFILES_DIRS</span></code> exists. While this is only a leftover from
previous versions of LAVA installer that is not needed anymore.</p>
<p>Once the changes are complete, ensure the settings are loaded by restarting
both apache2 and django:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">service</span> <span class="n">lava</span><span class="o">-</span><span class="n">server</span><span class="o">-</span><span class="n">gunicorn</span> <span class="n">restart</span>
<span class="n">sudo</span> <span class="n">apache2ctl</span> <span class="n">restart</span>
</pre></div>
</div>
</section>
<section id="performance-overhead">
<h3>Performance overhead<a class="headerlink" href="#performance-overhead" title="Permalink to this heading">¶</a></h3>
<p>Keep in mind that django-debug-toolbar has some overhead on the web page
generation and should only be used while debugging.</p>
<p>Django-debug-toolbar can be disabled, while not debugging, by changing the
value of <code class="docutils literal notranslate"><span class="pre">USE_DEBUG_TOOLBAR</span></code> in <code class="docutils literal notranslate"><span class="pre">/etc/lava-server/settings.conf</span></code> to
<code class="docutils literal notranslate"><span class="pre">false</span></code> or by changing the <code class="docutils literal notranslate"><span class="pre">̀DEBUG</span></code> level in
<code class="docutils literal notranslate"><span class="pre">/etc/lava-server/settings.conf</span></code> to <code class="docutils literal notranslate"><span class="pre">DEBUG:</span> <span class="pre">false</span></code>.</p>
<p>Ensure the settings are reloaded by restarting both apache2 and django:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sudo</span> <span class="n">service</span> <span class="n">lava</span><span class="o">-</span><span class="n">server</span><span class="o">-</span><span class="n">gunicorn</span> <span class="n">restart</span>
<span class="n">sudo</span> <span class="n">apache2ctl</span> <span class="n">restart</span>
</pre></div>
</div>
</section>
</section>
</section>


    </div>
      
  </div>
</div>
<footer class="footer">
  <div class="container">
    <p class="pull-right">
      <a href="#">Back to top</a>
      
    </p>
    <p>
        &copy; Copyright 2010-2019, Linaro Limited.<br/>
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 5.3.0.<br/>
    </p>
  </div>
</footer>
  </body>
</html>